using System;
using System.Collections.Generic;
using System.Windows.Forms;
using AssetManagementSystem.Model;
using AssetManagementSystem.Utils;
using AssetManagementSystem.Utils.Events;

namespace AssetManagementSystem.View.Controls {
    public partial class UIAssetEditor : Form {

        public EventHandler<AssetPropertiesEventArgs> Delete_Properties;
        public EventHandler<AssetEventArgs> Save_Clicked;
        public const string EDIT = "Edit";
        public const string NEW = "New";
        public const string TYPE_KEY = "Asset";

        private List<UIPropertyEditor> propEditors;
        private Dictionary<string, string> assetProps;
        private Dictionary<string, string> propsToDelete;

        //Constructor for new asset
        public UIAssetEditor(Dictionary<string, Group> groups) {
            InitializeComponent();
            SetGroups(groups);
            assetProps = new Dictionary<string, string>();
            propEditors = new List<UIPropertyEditor>();
            setTitle(NEW + " " + TYPE_KEY);
        }

        //Constructor for edting an existing asset
        public UIAssetEditor(Dictionary<string, Group> groups, Asset existingAsset) {
            InitializeComponent();
            propsToDelete = new Dictionary<string, string>();
            //Set Form Data from Existing Asset
            SetGroups(groups);
            ddAssetGroup.SelectedItem = existingAsset.GroupName;
            assetProps = existingAsset.Properties;
            txtAssetId.Text = existingAsset.Id;
            txtAssetId.Enabled = false;
            txtAssetName.Text = existingAsset.Name;
            txtAssetDescription.Text = existingAsset.Description;
            propEditors = new List<UIPropertyEditor>();
            setTitle(EDIT + " " + TYPE_KEY);
            RefreshPropertyList();
        }

        public void SetGroups(Dictionary<string, Group> groups) {
            this.ddAssetGroup.Items.Clear();
            foreach (KeyValuePair<string,Group> group in groups) {
                this.ddAssetGroup.Items.Add(group.Value.Name);
            }
        }

        private void UIAssetEditor_Load(object sender, EventArgs e) {
        }

        public string TitleText {
            get { return lblTitle.Text; }
            set { setTitle(value); }
        }

        private void setTitle(string text) {
            lblTitle.Text = text;
            this.Text = text;
        }

        private void splitContainer5_Panel2_Paint(object sender, PaintEventArgs e) {

        }

        private void btnPropAdd_Click(object sender, EventArgs e) {
            UIPropertyEditor propEdit = new UIPropertyEditor();
            propEdit.Save_Clicked += new EventHandler(Property_Saved);
            propEdit.Show();
            propEditors.Add(propEdit);
        }

        private void Property_Saved(object sender, EventArgs args) {
            //Get the real arguments and the sender ui.
            Dictionary<string, string> realArgs = ((DictionaryEventArgs)args).Args;
            UIPropertyEditor propSender = (UIPropertyEditor)sender;

            if(realArgs.ContainsValue(UIPropertyEditor.EDIT)){
                //Find the existing property
                if (assetProps.ContainsKey(realArgs[UIPropertyEditor.NAME])) {
                    //it already exists, so update it
                    assetProps[realArgs[UIPropertyEditor.NAME]] = realArgs[UIPropertyEditor.VALUE];
                    propSender.Close();
                    RefreshPropertyList();
                } else {
                    //it didn't exist, cannot be updated.
                    MessageBox.Show("A property with that name cannot be found, was it deleted before saving changes?");
                }
                assetProps[realArgs[UIPropertyEditor.NAME]] = realArgs[UIPropertyEditor.VALUE];
            }else if(realArgs.ContainsValue(UIPropertyEditor.NEW)){
                //Make sure property doesn't already exist.
                if(assetProps.ContainsKey(realArgs[UIPropertyEditor.NAME])){
                    //it already exists, so cannot be added.
                    MessageBox.Show("A property with that name already exists, another cannot be added.");
                }else{
                    //Remove it from the delete list
                    if (propsToDelete != null && propsToDelete.ContainsKey(realArgs[UIPropertyEditor.NAME])) {
                        propsToDelete.Remove(realArgs[UIPropertyEditor.NAME]);
                    }
                    //it didn't exist, so add it and get rid of the property editor window.
                    assetProps.Add(realArgs[UIPropertyEditor.NAME], realArgs[UIPropertyEditor.VALUE]);
                    propSender.Close();
                    RefreshPropertyList();
                }
            }
        }

        private void RefreshPropertyList() {
            gridAssetProperties.Rows.Clear();
            foreach (KeyValuePair<string, string> pair in assetProps) {
                gridAssetProperties.Rows.Add(pair.Key, pair.Value);
            }
        }

        private void UIAssetEditor_FormClosing(object sender, FormClosingEventArgs e) {
            foreach (UIPropertyEditor propEditor in propEditors) {
                propEditor.Close();
            }
        }

        private void btnPropEdit_Click(object sender, EventArgs e) {
            if (gridAssetProperties.Rows.GetRowCount(DataGridViewElementStates.Selected) > 0) {
                UIPropertyEditor propEdit = new UIPropertyEditor(
                    gridAssetProperties.SelectedRows[0].Cells["Property"].Value.ToString(),
                    gridAssetProperties.SelectedRows[0].Cells["Value"].Value.ToString()
                    );
                propEdit.Save_Clicked += new EventHandler(Property_Saved);
                propEdit.Show();
                propEditors.Add(propEdit);
            }
        }

        private void btnPropDel_Click(object sender, EventArgs e) {
            if (gridAssetProperties.Rows.GetRowCount(DataGridViewElementStates.Selected) > 0) {
                if (propsToDelete != null) {
                    propsToDelete.Add(gridAssetProperties.SelectedRows[0].Cells["Property"].Value.ToString(), gridAssetProperties.SelectedRows[0].Cells["Value"].Value.ToString());
                }
                assetProps.Remove(gridAssetProperties.SelectedRows[0].Cells["Property"].Value.ToString());
                RefreshPropertyList();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e) {
            this.Close();
        }

        private void btnSave_Click(object sender, EventArgs e) {
            if (ddAssetGroup.SelectedIndex < 0) {
                MessageBox.Show("A group must be selected");
            } else if (txtAssetId.Text == "") {
                MessageBox.Show("A unique asset id must be provided");
            } else {
                if (propsToDelete != null) {
                    Delete_Properties.Invoke(this, new AssetPropertiesEventArgs(txtAssetId.Text, propsToDelete));
                }
                Save_Clicked.Invoke(this, new AssetEventArgs(new Asset(txtAssetId.Text, txtAssetName.Text, ddAssetGroup.Items[ddAssetGroup.SelectedIndex].ToString(), txtAssetDescription.Text, assetProps)));
            }
        }
    }
}
